import React, { PureComponent } from 'react'
import {
  DatePicker, Form, Input, message, Radio, Select,
} from 'antd'
import moment from 'moment'
import { regExp } from '@/utils/regExp'
import { getHashParameterByName } from '@/utils/helper'
import {
  getRule, getRuleTemplates, getTableFields, saveRule,
} from '../api'

const name = regExp.name(2, 32)

const { Option } = Select

class DataQualityCreate extends PureComponent {
  constructor(props) {
    super(props)
    this.state = {
      tblId: getHashParameterByName('tblId'),
      // hasPartition: getHashParameterByName('hasPartition'),
      tableName: getHashParameterByName('tableName'),
    }
    this.form = React.createRef()
  }

  componentDidMount() {
    const { tableName, tblId } = this.state
    this.setState({
      isMdTable: /^md_/.test(tableName),
    })
    this.getRule()
    this.getTableFields(tblId)
  }

  getRule = () => {
    const { id } = this.props
    this.setState({
      id,
    })
    getRule({ id }).then((res) => {
      if (res.status === 200) {
        if (!res.data) return
        if (res.data.ruleType || res.data.ruleType === 0) this.getRuleTemplates(res.data)
        res.data.ruleConditions && res.data.ruleCondition
          ? res.data.ruleConditions.map((obj) => {
            obj.items
              && obj.items.map((o, k) => {
                o.value = JSON.parse(res.data.ruleCondition)[k].value
              })
          })
          : null
        this.setState(
          {
            max: res.data.max,
            min: res.data.min,
            fieldTypes: res.data.fieldTypes,
            compareTypes: res.data.compareTypes,
            expectValue: res.data.expectValue,
            templateId: res.data.templateId,
            ruleTemplatesItem: res.data.ruleConditions
              ? { ruleConditions: res.data.ruleConditions }
              : null,
          },
          () => {
            const val = {
              ruleName: res.data.ruleName,
              remark: res.data.remark,
              diySql: res.data.diySql,
              new: res.data.max || res.data.min || 0,
              ruleStrength: res.data.ruleStrength,
              ruleType: res.data.ruleType,
              templateFilter: res.data.templateFilter,
              templateId: res.data.templateId,
              fieldNames: res.data.fieldNames && res.data.fieldNames.split(','),
              ruleCompareType: res.data.ruleCompareType && res.data.ruleCompareType.split(','),
              ruleExpectValue: res.data.ruleExpectValue,
            }
            res.data.ruleCondition
              && JSON.parse(res.data.ruleCondition).map((obj) => {
                if (obj.key === 'date') {
                  val[obj.key] = moment(obj.value, 'YYYY-MM-DD')
                } else {
                  val[obj.key] = obj.value
                }
              })
            this.form && this.form.current.setFieldsValue({
              ...val,
            })
          },
        )
      } else {
        message.error(res.msg)
      }
    })
  }

  getTableFields = (tblId) => {
    getTableFields({ tblId }).then((res) => {
      if (res.status === 200) {
        this.setState({
          fields: res.data,
        })
      } else {
        this.setState({
          fields: [],
        })
      }
    })
  }

  getRuleTemplates = (data) => {
    getRuleTemplates({
      templateTableType: data.ruleType,
    }).then((res) => {
      if (res.status === 200) {
        this.setState({
          ruleTemplates: res.data,
        })
      } else {
        this.setState({
          ruleTemplates: [],
        })
      }
    })
  }

  /**
   * 构建sql
   */
  // sql = () => {
  //   const { partitionExpression } = this.props
  //   const { hasPartition, tableName } = this.state
  //   const values = this.form.current.getFieldsValue()
  //   if (values.ruleDiyStatisticalModel && values.fieldNames && tableName) {
  //     const arr = []
  //     values.fieldNames.map((val) => {
  //       arr.push(
  //         `select ${values.ruleDiyStatisticalModel}(${val}) from ${tableName
  //         } ${hasPartition == 0 || partitionExpression === undefined
  //           ? ''
  //           : `where ${partitionExpression}\n`
  //         }`,
  //       )
  //     })
  //     this.setState({
  //       sql: arr.join(),
  //     })
  //   }
  // };

  valuesChange = (value, allValues) => {
    if (allValues.ruleType || allValues.ruleType === 0) { this.getRuleTemplates(allValues) }
  }

  /**
   * 获取内置模板的规则
   */
  modelRule = () => {
    const { setFieldsValue } = this.form.current || {}

    const {
      ruleTemplatesItem, compareTypes, expectValue, ruleTemplates, isMdTable, templateId,
    } = this.state
    const r = '^[0-9,\,]*$'
    return (
      <div>
        <Form.Item
          label="规则类型"
          name="ruleType"
          rules={[{ required: true, message: '规则类型不能为空' }]}
        >
          <Select
            onChange={(value) => {
              setFieldsValue({
                templateId: undefined,
              })
              this.setState(
                {
                  // ruleType: value,
                  ruleTemplatesItem: null,
                  compareTypes: null,
                  expectValue: null,
                },
              )
            }}
            placeholder="请选择规则类型"
          >
            <Option value={0}>字段级规则</Option>
            {/* <Option value={1}>表级规则</Option> */}
          </Select>
        </Form.Item>

        <Form.Item
          label="规则模板"
          name="templateId"
          rules={[{ required: true, message: '规则模板不能为空' }]}
        >
          <Select
            placeholder="请选择规则模板"
            onChange={(value, e) => {
              this.form && this.form.current.setFieldsValue({
                ruleCompareType: undefined,
              })
              this.setState(
                {
                  ruleTemplatesItem: e.item,
                  compareTypes: e.item.compareTypes,
                  expectValue: e.item.expectValue,
                  templateId: e.item.id,
                },
              )
            }}
          >
            {ruleTemplates
              && ruleTemplates.map((obj, k) => (
                <Option
                  key={k}
                  item={obj}
                  value={obj.id}
                >
                  {obj.name}
                </Option>
              ))}
          </Select>
        </Form.Item>
        <Form.Item
          label="过滤条件"
          name="templateFilter"
        >
          <Input.TextArea placeholder="请输入过滤条件" />
        </Form.Item>

        {compareTypes && (
          <Form.Item
            label="比较方式"
            name="ruleCompareType"
            style={{ clear: 'both' }}
            rules={[
              {
                required: true,
                message: '比较方式不能为空',
              },
            ]}
          >
            <Select
              mode={templateId == 9 || templateId == 4 ? 'multiple' : null}
              showSearch
              optionFilterProp="children"
              filterOption={(input, option) => option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
              placeholder="请选择比较方式"
            >
              {compareTypes.map((obj, key) => (
                <Option key={key} value={String(obj.compareType)}>
                  {obj.desc}
                </Option>
              ))}
            </Select>
          </Form.Item>
        )}
        {ruleTemplatesItem
          && ruleTemplatesItem.ruleConditions
          && ruleTemplatesItem.ruleConditions.length
          && ruleTemplatesItem.ruleConditions[0].items.length > 1
          ? (
            <Form.Item
              label={ruleTemplatesItem.ruleConditions[0].name}
              name="new"
              rules={[
                {
                  required: true,
                  message: `${ruleTemplatesItem.ruleConditions[0].name}不能为空`,
                },
              ]}
            >
              <div className="site-input-group-wrapper">
                <Input.Group compact>
                  <Input
                    style={{ width: '1.5rem' }}
                    placeholder="最小值"
                    type="number"
                    min={0}
                    value={ruleTemplatesItem.ruleConditions[0].items[0].value}
                    onChange={(e) => {
                      ruleTemplatesItem.ruleConditions[0].items[0].value = e.target.value
                      this.setState({
                        min: e.target.value,
                      })
                    }}
                  />
                  <Input
                    className="site-input-split"
                    style={{
                      width: 30,
                      borderLeft: 0,
                      borderRight: 0,
                      pointerEvents: 'none',
                    }}
                    placeholder="~"
                    disabled
                  />
                  <Input
                    className="site-input-right"
                    style={{
                      width: '1.5rem',
                    }}
                    min={0}
                    type="number"
                    placeholder="最大值"
                    value={ruleTemplatesItem.ruleConditions[0].items[1].value}
                    onChange={(e) => {
                      ruleTemplatesItem.ruleConditions[0].items[1].value = e.target.value
                      this.setState({
                        max: e.target.value,
                      })
                    }}
                  />
                </Input.Group>
              </div>
            </Form.Item>
          )
          : ruleTemplatesItem
          && ruleTemplatesItem.ruleConditions
          && ruleTemplatesItem.ruleConditions[0]
          && ruleTemplatesItem.ruleConditions[0].items
          && ruleTemplatesItem.ruleConditions[0].items.map(
            (obj, k) => (
              <div key={k}>
                <Form.Item
                  label={ruleTemplatesItem.ruleConditions[0].name}
                  name={obj.key}
                  rules={[
                    {
                      required: true,
                      message: `${ruleTemplatesItem.ruleConditions[0].name}不能为空`,
                    },
                    {
                      required: false,
                      pattern: obj.dataType == 'number' ? new RegExp(r) : null,
                      message: '只支持数字和逗号',
                    },
                  ]}
                >
                  {{
                    number: <Input
                      placeholder={obj.placeholder}
                      onChange={(e) => {
                        obj.value = e.target.value
                      }}
                    />,
                    text: <Input
                      onChange={(e) => {
                        obj.value = e.target.value
                      }}
                      placeholder={obj.placeholder}
                    />,
                    date: <DatePicker
                      onChange={(_date, dateString) => {
                        obj.value = dateString
                      }}
                      placeholder={obj.placeholder}
                    />,
                  }[obj.dataType]}
                </Form.Item>
              </div>
            ),
          )}
        {expectValue && (
          <Form.Item
            label="期望值"
            name="ruleExpectValue"
            rules={[
              {
                required: true,
                message: '期望值不能为空',
              },
            ]}
          ><Input placeholder="请输入期望值" type="number" />
          </Form.Item>
        )}
      </div>
    )
  };

  /**
   * 获取自定义模板的规则
   */
  customRule = () => (
    <div>
      <Form.Item label="SQL" name="diySql">
        <Input.TextArea
          placeholder="请输入SQL"
          autoSize={{ minRows: 3, maxRows: 5 }}
        />
      </Form.Item>
      <Form.Item
        label="比较方式"
        name="ruleCompareType"
        rules={[
          {
            required: true,
            message: '比较方式不能为空',
          },
        ]}
      >
        <Select placeholder="请选择比较方式">
          <Option value="0">大于</Option>
          <Option value="1">大于等于</Option>
          <Option value="2">等于</Option>
          <Option value="3">小于</Option>
          <Option value="4">小于等于</Option>
          <Option value="5">不等于</Option>
        </Select>
      </Form.Item>
      <Form.Item
        label="期望值"
        name="ruleExpectValue"
        rules={[
          {
            required: true,
            message: '期望值不能为空',
          },
        ]}
      ><Input placeholder="请输入期望值" type="number" />
      </Form.Item>
    </div>
  );

  // eslint-disable-next-line react/no-unused-class-component-methods
  onFinish = () => {
    const {
      fieldTypes, tblId, max, min, tableName, ruleTemplatesItem, id,
    } = this.state
    const { ruleDiy, partitionId, partitionExpression } = this.props
    this.form.current.validateFields().then(values => {
      saveRule({
        ...values,
        ruleDiy,
        partitionId,
        tblName: tableName,
        fieldTypes,
        tblId,
        id,
        fieldNames: Array.isArray(values.fieldNames) ? values.fieldNames?.join(',') : values.fieldNames,
        ruleCompareType: Array.isArray(values.ruleCompareType) ? values.ruleCompareType?.join(',') : values.ruleCompareType,
        max,
        min,
        partitionExpression,
        ruleCondition:
          ruleTemplatesItem
            && ruleTemplatesItem.ruleConditions
            && ruleTemplatesItem.ruleConditions[0]
            ? JSON.stringify(ruleTemplatesItem.ruleConditions[0].items)
            : null,
      }).then((res) => {
        if (res.status === 200) {
          message.success(res.msg)
          this.props.show()
        } else {
          message.error(res.msg)
        }
      })
    })
  }

  render() {
    const {
      fields,
    } = this.state
    const { ruleDiy } = this.props
    return (
      <Form
        colon={false}
        labelCol={{ span: 4 }}
        wrapperCol={{ span: 20 }}
        onValuesChange={this.valuesChange}
        ref={this.form}
      >
        <Form.Item
          label="规则名称"
          name="ruleName"
          rules={[
            { required: true, message: '请输入规则名称' },
            {
              pattern: new RegExp(name.reg, 'g'),
              message: name.text,
            },
          ]}
        >

          <Input placeholder="请输入规则名称" />
        </Form.Item>
        {ruleDiy == 0 ? (
          <Form.Item
            label="规则字段"
            name="fieldNames"
            rules={[
              { required: true, message: '请选择规则字段' },
              ({}) => ({
                validator(_, value) {
                  if (value?.length) {
                    let totleNameLength = 0
                    let totleTypeLength = 0
                    value.forEach(element => {
                      totleNameLength += (element.length + 1)
                      const obj = (fields || []).find((field) => field.fieldName === element)
                      if (obj) {
                        totleTypeLength += (obj.fieldType.length + 1)
                      }
                    })
                    if (totleNameLength >= 250 || totleTypeLength >= 250) {
                      return Promise.reject(new Error('所选字段的字符数总和不能超过250'))
                    }
                  }
                  return Promise.resolve()
                },
              }),
            ]}
          >
            <Select
              mode="multiple"
              placeholder="请选择规则字段"
              showSearch
              optionFilterProp="children"
              filterOption={(input, option) => option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
              onChange={(value, e) => {
                const arr = []
                e.map((o) => {
                  arr.push(o.props.type)
                })
                this.setState(
                  {
                    fieldTypes: arr && arr.join(','),
                  },
                )
              }}
            >
              {fields && fields.map((item, i) => (
                <Option
                  key={i}
                  type={item.fieldType}
                  value={item.fieldName}
                >{item.fieldName}
                </Option>
              ))}
            </Select>
          </Form.Item>
        ) : null}
        <Form.Item
          label="强弱"
          name="ruleStrength"
          rules={[{ required: true, message: '请选择强弱' }]}
        >
          <Radio.Group>
            <Radio value={0}>强</Radio>
            <Radio value={1}>弱</Radio>
          </Radio.Group>
        </Form.Item>
        {(ruleDiy || ruleDiy === 0) && {
          0: this.modelRule(),
          1: this.customRule(),
        }[ruleDiy]}
        <Form.Item
          label="描述"
          name="remark"
          rules={[
            {
              required: false,
              pattern: new RegExp(regExp.proName(0, 128).reg, 'g'),
              message: regExp.proName(0, 128).text,
            },
          ]}
        >
          <Input.TextArea placeholder="请输入规则描述" />
        </Form.Item>
      </Form>
    )
  }
}

export default DataQualityCreate
